package com.itheima.cs.common.nbdb;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;

import android.content.SharedPreferences;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import com.itheima.cs.R;
import com.itheima.cs.dao.MaterialDao;
import com.itheima.cs.dao.dbd.InternalTransferDao;
import com.itheima.cs.dao.dbd.WarehouseDao;
import com.itheima.cs.entity.dbd.InternalTransfer;
import com.itheima.cs.entity.dbd.WarehouseInfo;
import com.itheima.cs.utils.LoginManager;

import org.json.JSONArray;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class InternalTransferFormActivity extends AppCompatActivity {
    private static final int REQUEST_OUT_STOCK = 1;
    private static final int REQUEST_IN_STOCK = 2;

    private EditText etOutNumber, etInNumber, etQuantity;
    private TextView tvOutName, tvOutFwcmpers,tvInName, tvFwcmPers;
    private TextView tvMaterialCode, tvMaterialName, tvMaterialSpec, tvDate;
    private String materialCode, materialName, materialSpec,dbdUUID;

    private ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_internal_transfer_form);


        Intent intent = getIntent();
        materialCode = intent.getStringExtra("code");
        materialName = intent.getStringExtra("name");
        materialSpec = intent.getStringExtra("spec");
        dbdUUID = intent.getStringExtra("dbdUUID");

        initViews();
        setupToolbar();
        setupDate();
        setupAutoFill();
    }

    private void initViews() {
        etOutNumber = findViewById(R.id.et_out_number);
        tvOutName = findViewById(R.id.tv_out_name);
        tvOutFwcmpers = findViewById(R.id.tv_out_fwcmpers);
        etInNumber = findViewById(R.id.et_in_number);
        tvInName = findViewById(R.id.tv_in_name);
        tvFwcmPers = findViewById(R.id.tv_fwcmpers);
        etQuantity = findViewById(R.id.et_quantity);

        tvMaterialCode = findViewById(R.id.tv_material_code);
        tvMaterialName = findViewById(R.id.tv_material_name);
        tvMaterialSpec = findViewById(R.id.tv_material_spec);
        tvDate = findViewById(R.id.tv_date);

        tvMaterialCode.setText(materialCode);
        tvMaterialName.setText(materialName);
        tvMaterialSpec.setText(materialSpec);

        findViewById(R.id.btn_select_out).setOnClickListener(v -> selectStock(REQUEST_OUT_STOCK));
        findViewById(R.id.btn_select_in).setOnClickListener(v -> selectStock(REQUEST_IN_STOCK));

        Button btnSubmit = findViewById(R.id.btn_submit);
        btnSubmit.setOnClickListener(v -> submitTransfer());
    }

    private void setupToolbar() {
        Toolbar toolbar = findViewById(R.id.toolbar_add_internal_transfer_form);
        setSupportActionBar(toolbar);
        toolbar.setNavigationOnClickListener(v -> finish());
    }

    private void setupDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
        tvDate.setText(sdf.format(new Date()));
    }

    private void selectStock(int requestCode) {
        Intent intent = new Intent(this, StockSelectActivity.class);
        intent.putExtra("stock_property", "1");
        startActivityForResult(intent, requestCode);
    }

    private void setupAutoFill() {
        etOutNumber.addTextChangedListener(new TextWatcher() {
            @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            @Override public void onTextChanged(CharSequence s, int start, int before, int count) {}

            @Override
            public void afterTextChanged(Editable s) {
                if (s.length() > 0) {
                    new Thread(() -> {
                        WarehouseInfo stock = new WarehouseDao().getByNumber(s.toString(), "1");
                        runOnUiThread(() -> tvOutName.setText(stock != null ? stock.getName() : ""));

                    }).start();
                }
            }
        });

        etInNumber.addTextChangedListener(new TextWatcher() {
            @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            @Override public void onTextChanged(CharSequence s, int start, int before, int count) {}

            @Override
            public void afterTextChanged(Editable s) {
                if (s.length() > 0) {
                    new Thread(() -> {
                        WarehouseInfo stock = new WarehouseDao().getByNumber(s.toString(), "1");

                        runOnUiThread(() -> {
                            tvInName.setText(stock != null ? stock.getName() : "");
                            tvFwcmPers.setText(stock != null ? stock.getFwcmPers() : "");
                        });
                    }).start();
                }
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && data != null) {
            WarehouseInfo stock = data.getParcelableExtra("selected_stock");
            if (requestCode == REQUEST_OUT_STOCK) {
                etOutNumber.setText(stock.getNumber());
                tvOutName.setText(stock.getName());
                tvOutFwcmpers.setText(stock.getFwcmPers());
            } else if (requestCode == REQUEST_IN_STOCK) {
                etInNumber.setText(stock.getNumber());
                tvInName.setText(stock.getName());
                tvFwcmPers.setText(stock.getFwcmPers());
            }
        }
    }

    private void submitTransfer() {
        String outNumber = etOutNumber.getText().toString().trim();
        String outName = tvOutName.getText().toString().trim();
        String inNumber = etInNumber.getText().toString().trim();
        String inName = tvInName.getText().toString().trim();
        String quantity = etQuantity.getText().toString().trim();

        String outFwcmpers = tvOutFwcmpers.getText().toString().trim();
        String inFwcmpers = tvFwcmPers.getText().toString().trim();


        if (outNumber.isEmpty() || inNumber.isEmpty()) {
            Toast.makeText(this, "请选择调出/调入仓库", Toast.LENGTH_SHORT).show();
            return;
        }
        if (outNumber.equals(inNumber)) {
            Toast.makeText(this, "调出和调入仓库不能相同", Toast.LENGTH_SHORT).show();
            return;
        }
        if (outName.isEmpty()) {
            Toast.makeText(this, "请选择有效的调出仓库", Toast.LENGTH_SHORT).show();
            return;
        }
        if (inName.isEmpty()) {
            Toast.makeText(this, "请选择有效的调入仓库", Toast.LENGTH_SHORT).show();
            return;
        }
        if (quantity.isEmpty()) {
            Toast.makeText(this, "请输入调拨数量", Toast.LENGTH_SHORT).show();
            return;
        }

        // 根据UUID和调入、调出仓库判断当前调拨唯一性，一框货调入调出一个仓库只能有一次
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<List<InternalTransfer>> future = executor.submit(new Callable<List<InternalTransfer>>() {
            @Override
            public List<InternalTransfer> call() throws Exception {
                // 在这里执行耗时操作
                return new MaterialDao().getDBDList(materialCode, dbdUUID, etOutNumber.getText().toString(), etInNumber.getText().toString());
            }
        });
        try {
            List<InternalTransfer> result = future.get(); // 获取结果
            if (result != null && !result.isEmpty()) {
                String errorMessage = "该物料二维码（"+materialCode+"）对应的货物在本仓库已经录入，请勿重复上传！";
                Toast.makeText(InternalTransferFormActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
                return;
            }
            // 更新UI
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        } finally {
            executor.shutdown();
        }

        SharedPreferences prefs = getSharedPreferences("user_info", MODE_PRIVATE);
        String userId = prefs.getString("user_id", "unknown");

        SimpleDateFormat dbDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        String fullDate = dbDateFormat.format(new Date());


        InternalTransfer transfer = new InternalTransfer();
        transfer.setDocType("内部");
        transfer.setOutWarehouseNo(outNumber);
        transfer.setOutWarehouseName(outName);
        transfer.setInWarehouseNo(inNumber);
        transfer.setInWarehouseName(inName);
        transfer.setMaterialCode(materialCode);
        transfer.setMaterialName(materialName);
        transfer.setMaterialSpec(materialSpec);
        transfer.setEtQuantity(quantity);
        transfer.setDate(fullDate);
        transfer.setUserId(userId);
        transfer.setDbdUUID(dbdUUID);


        new Thread(() -> {
            Integer localId = new InternalTransferDao().createTransferAndReturnId(transfer);
            runOnUiThread(() -> {
                if (localId != null) {
                    showLoading("提交中...");
                    Toast.makeText(this, "数据库提交成功", Toast.LENGTH_SHORT).show();
                    performLoginAndSubmit(transfer, localId);
                } else {
                    Toast.makeText(this, "数据库提交失败", Toast.LENGTH_SHORT).show();
                    dismissLoading();
                }
            });
        }).start();
    }

    private void performLoginAndSubmit(InternalTransfer transfer, int localId) {
        SharedPreferences prefs = getSharedPreferences("user_info", MODE_PRIVATE);
        String username = LoginManager.getInstance(InternalTransferFormActivity.this).getUsername();
        String password = LoginManager.getInstance(InternalTransferFormActivity.this).getPassword();

        LoginManager.getInstance(this).login(username, password, tvOutFwcmpers.getText().toString().trim(), new LoginManager.LoginCallback() {
            @Override
            public void onSuccess() {

                new Thread(() -> sendTransferToApi(transfer, localId)).start();
            }

            @Override
            public void onFailure(String errorMessage) {
                runOnUiThread(() -> {
                    dismissLoading();
                    Toast.makeText(InternalTransferFormActivity.this,
                            "登录失败: " + errorMessage, Toast.LENGTH_SHORT).show();
                });
            }
        });
    }


    private void showLoading(String msg) {
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage(msg);
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    private void dismissLoading() {
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    private void sendTransferToApi(InternalTransfer transfer, int localId) {
        try {
            JSONObject requestBody = new JSONObject();
            JSONObject data = new JSONObject();
            JSONObject model = new JSONObject();

            model.put("FBillTypeID", new JSONObject().put("FNUMBER", "ZJDB01_SYS"));
            model.put("FBizType", "NORMAL");
            model.put("FTransferDirect", "GENERAL");
            model.put("FTransferBizType", "InnerOrgTransfer");

            model.put("FStockOutOrgId", new JSONObject().put("FNumber", "001"));
            model.put("FOwnerTypeOutIdHead", "BD_OwnerOrg");
            model.put("FOwnerOutIdHead", new JSONObject().put("FNumber", "001"));

            model.put("FStockOrgId", new JSONObject().put("FNumber", "001"));
            model.put("FOwnerTypeIdHead", "BD_OwnerOrg");
            model.put("FOwnerIdHead", new JSONObject().put("FNumber", "001"));

            model.put("FDate", transfer.getDate());

            SharedPreferences prefs = getSharedPreferences("user_info", MODE_PRIVATE);
            String username = prefs.getString("user_name", "unknown");
            model.put("F_qqqq_Base", new JSONObject().put("FUserAccount", tvFwcmPers.getText().toString()));
//            // 手动指定审核人 FApproverId
//            model.put("FApproverId", new JSONObject().put("FUserAccount", tvFwcmPers.getText().toString()));
//            // 手动指定创建人为调出仓库管理员
//            model.put("FCreatorId", new JSONObject().put("FUserAccount", tvOutFwcmpers.getText().toString()));
            // 指定扫码操作员
            String userEmpNumber = prefs.getString("user_emp_number", "unknown");
            if (!"unknown".equals(userEmpNumber)) {
                // 设置当前调拨单的扫码操作员
                model.put("FSMEmpInfo", new JSONObject().put("FStaffNumber", userEmpNumber));
            }

            JSONArray fBillEntry = new JSONArray();
            JSONObject entry = new JSONObject();
            entry.put("F_qqqq_Text1", "SM-NORMAL".concat(localId+""));
            entry.put("FMaterialId", new JSONObject().put("FNumber", transfer.getMaterialCode()));
            entry.put("FQty", transfer.getEtQuantity());
            entry.put("FSrcStockId", new JSONObject().put("FNumber", transfer.getOutWarehouseNo()));
            entry.put("FDestStockId", new JSONObject().put("FNumber", transfer.getInWarehouseNo()));
            entry.put("FSrcStockStatusId", new JSONObject().put("FNumber", "KCZT01_SYS"));
            entry.put("FDestStockStatusId", new JSONObject().put("FNumber", "KCZT01_SYS"));
            entry.put("FOwnerTypeOutId", "BD_OwnerOrg");
            entry.put("FOwnerOutId", new JSONObject().put("FNumber", "001"));
            entry.put("FOwnerTypeId", "BD_OwnerOrg");
            entry.put("FOwnerId", new JSONObject().put("FNumber", "001"));
            fBillEntry.put(entry);
            model.put("FBillEntry", fBillEntry);

            data.put("Model", model);
            requestBody.put("data", data);
            requestBody.put("formid", "STK_TransferDirect");


            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .build();

            RequestBody body = RequestBody.create(
                    requestBody.toString(),
                    MediaType.parse("application/json")
            );

            String url = "http://192.168.16.201:8090/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save.common.kdsvc";
            Request request = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Cookie", getCookies())
                    .build();

            Response response = client.newCall(request).execute();
            int retValue = handleApiResponse(response, localId, 0);
            if (retValue==-1) {
                //ERP单据保存失败后不进行后续操作
                //runOnUiThread(() -> Toast.makeText(this, "ERP表单保存请求失败", Toast.LENGTH_SHORT).show());
                return;
            }
            //ERP单据保存成功后，则进行ERP单据提交
            submitBillInERP(retValue, localId);

        } catch (Exception e) {
            runOnUiThread(() -> Toast.makeText(this, "ERP表单保存请求异常: " + e.getMessage(), Toast.LENGTH_SHORT).show());
        }
    }

    /**
     * 解析ERP请求返回参数
     * @param response 返回响应字符串
     * @param localId 调拨单dbd_id
     * @param reqType 请求类型：0：保存表单请求；1：提交表单请求
     */
    private int handleApiResponse(Response response, int localId, int reqType) throws Exception {
        int retValue=-1;
        String responseBody = response.body().string();
        JSONObject json = new JSONObject(responseBody);
        JSONObject result = json.getJSONObject("Result");
        JSONObject status = result.getJSONObject("ResponseStatus");

        if (status.getBoolean("IsSuccess")) {
            JSONArray entities = status.getJSONArray("SuccessEntitys");
            if (entities.length() > 0) {
                JSONObject entity = entities.getJSONObject(0);
                String number = entity.getString("Number");
                int id = entity.getInt("Id");
                retValue = id;

                boolean success = new InternalTransferDao().updateTransferInfo(localId, number, id, reqType);

                runOnUiThread(() -> {
                    if (success) {
                        if (reqType == 1){
                            //表单提交成功后才进行跳转
                            Intent intent = new Intent(this, InternalTransferDetailActivity.class);
                            intent.putExtra("localId", localId);
                            startActivity(intent);
                            finish();
                            dismissLoading();
                        }
                        String info = reqType==0?"ERP表单保存成功":"ERP表单提交成功";
                        int duration = reqType==0?Toast.LENGTH_SHORT:Toast.LENGTH_LONG;
                        Toast.makeText(this, info, duration).show();
                    } else {
                        Toast.makeText(this, "数据库更新失败", Toast.LENGTH_SHORT).show();
                        dismissLoading();
                    }
                });
            }
        } else {
//            Log.e("JSON_ERROR", "原始响应内容:\n" + responseBody);
            int errorCode = status.getInt("ErrorCode");
            String toastStr = reqType==0?"ERP表单保存失败, 错误码：".concat(errorCode+""):"ERP表单提交失败, 错误码：".concat(errorCode+"");
            JSONArray errors = status.getJSONArray("Errors");
            if (errors.length() > 0) {
                JSONObject entityObj = errors.getJSONObject(0);
                String message = entityObj.getString("Message");
                if (!message.isEmpty()) {
                    toastStr = toastStr.concat(", 错误信息：").concat(message);
                }
            }
            String finalToastStr = toastStr;
            runOnUiThread(() -> Toast.makeText(this, finalToastStr, Toast.LENGTH_SHORT).show());
            if (reqType == 1){
                //表单已经保存成功，但是提交失败了，比如负库存，也弹窗提示并进行跳转
                Intent intent = new Intent(this, InternalTransferDetailActivity.class);
                intent.putExtra("localId", localId);
                startActivity(intent);
                finish();
                dismissLoading();
            } else {
                //如果是ERP表单保存就失败了，则直接结束
                dismissLoading();
            }
        }
        return retValue;
    }

    private void submitBillInERP (int billId, int localId) {
        //进行ERP单据提交
        try{
            JSONObject requestBody = new JSONObject();
            JSONObject data = new JSONObject();
//            data.put("CreateOrgId", "001");
//            String [] numberArray = new String[1];
//            numberArray[0]=number;
//            data.put("Numbers", numberArray);
            data.put("Ids", billId);
//            data.put("UseOrgId", "001");
            requestBody.put("data", data);
            requestBody.put("formid", "STK_TransferDirect");
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .build();

            RequestBody body = RequestBody.create(
                    requestBody.toString(),
                    MediaType.parse("application/json")
            );

            String url = "http://192.168.16.201:8090/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Submit.common.kdsvc";
            Request request = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Cookie", getCookies())
                    .build();
            Response submitResponse = client.newCall(request).execute();
            handleApiResponse(submitResponse, localId, 1);

        } catch (Exception e) {
            runOnUiThread(() -> Toast.makeText(this, "ERP表单提交请求异常: " + e.getMessage(), Toast.LENGTH_SHORT).show());
            dismissLoading();
        }
    }

    private String getCookies() {
        SharedPreferences sp = getSharedPreferences("session_cookie", MODE_PRIVATE);
        return "ASP.NET_SessionId=" + sp.getString("sessionId", "") +
                "; kdservice-sessionid=" + sp.getString("kdsvcSessionId", "");
    }

    @Override
    protected void onResume() {
        super.onResume();

    }
}